package scenic.study.thinkinjava.io;//: c11:CADState.java
// From 'Thinking in Java, 2nd ed.' by Bruce Eckel
// www.BruceEckel.com. See copyright notice in CopyRight.txt.
// Saving and restoring the state of a 
// pretend CAD system.

import java.io.*;
import java.util.*;

abstract class Shape implements Serializable {
    public static final int
            RED = 1, BLUE = 2, GREEN = 3;
    private int xPos, yPos, dimension;
    private static Random r = new Random();
    private static int counter = 0;

    abstract public void setColor(int newColor);

    abstract public int getColor();

    public Shape(int xVal, int yVal, int dim) {
        xPos = xVal;
        yPos = yVal;
        dimension = dim;
    }

    public String toString() {
        return getClass() +
                " color[" + getColor() +
                "] xPos[" + xPos +
                "] yPos[" + yPos +
                "] dim[" + dimension + "]\n";
    }

    public static Shape randomFactory() {
        int xVal = r.nextInt() % 100;
        int yVal = r.nextInt() % 100;
        int dim = r.nextInt() % 100;
        switch (counter++ % 3) {
            default:
            case 0:
                return new Circle(xVal, yVal, dim);
            case 1:
                return new Square(xVal, yVal, dim);
            case 2:
                return new Line(xVal, yVal, dim);
        }
    }
}

class Circle extends Shape {
    private static int color = RED;

    public Circle(int xVal, int yVal, int dim) {
        super(xVal, yVal, dim);
    }

    public void setColor(int newColor) {
        color = newColor;
    }

    public int getColor() {
        return color;
    }
}

class Square extends Shape {
    private static int color;

    public Square(int xVal, int yVal, int dim) {
        super(xVal, yVal, dim);
        color = RED;
    }

    public void setColor(int newColor) {
        color = newColor;
    }

    public int getColor() {
        return color;
    }
}

class Line extends Shape {
    private static int color = RED;

    public static void
    serializeStaticState(ObjectOutputStream os)
            throws IOException {
        os.writeInt(color);
    }

    public static void
    deserializeStaticState(ObjectInputStream os)
            throws IOException {
        color = os.readInt();
    }

    public Line(int xVal, int yVal, int dim) {
        super(xVal, yVal, dim);
    }

    public void setColor(int newColor) {
        color = newColor;
    }

    public int getColor() {
        return color;
    }
}

public class CADState {
    public static void main(String[] args)
            throws Exception {
        ArrayList shapeTypes, shapes;
        if (args.length == 0) {
            shapeTypes = new ArrayList();
            shapes = new ArrayList();
            // Add references to the class objects:
            shapeTypes.add(Circle.class);
            shapeTypes.add(Square.class);
            shapeTypes.add(Line.class);
            // Make some shapes:
            for (int i = 0; i < 10; i++)
                shapes.add(Shape.randomFactory());
            // Set all the static colors to GREEN:
            for (int i = 0; i < 10; i++)
                ((Shape) shapes.get(i))
                        .setColor(Shape.GREEN);
            // Save the state vector:
            ObjectOutputStream out =
                    new ObjectOutputStream(
                            new FileOutputStream("CADState.out"));
            out.writeObject(shapeTypes);
            Line.serializeStaticState(out);
            out.writeObject(shapes);
        } else { // There's a command-line argument
            ObjectInputStream in =
                    new ObjectInputStream(
                            new FileInputStream(args[0]));
            // Read in the same order they were written:
            shapeTypes = (ArrayList) in.readObject();
            Line.deserializeStaticState(in);
            shapes = (ArrayList) in.readObject();
        }
        // Display the shapes:
        System.out.println(shapes);
    }
} ///:~